package com.jimmyc.fall12.OpenClass;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;


import android.R.bool;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.res.AssetManager;
import android.graphics.Color;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;
import android.support.v4.app.NavUtils;

/* For now, I will parse the values of class terms, class categoris dynamically
 * by going to the website. This requires an internet connection. In the future
 * I will write a python script to generate an assets file by writing a python/linux script.
 * 
 * Next step: Fix sorting of classes
 * 			  Implement a stop button
 * 			  List the class that is being sought.
 * 
 * 
 * */
public class MainInterface extends Activity {
	private TextView displaySubject, displayClass, displayTerm;
	 private RadioGroup radioGroupClassTerms;
	 private RadioButton radioButtonSelTerm;
	 private ListView listViewSelCategory;
	 private ListView listViewSelClassName;
	////////use these to get the general format of a website
	private final String subjectSiteBegin =  "http://www.registrar.ucla.edu/schedule/crsredir.aspx?termsel=";
	private final String subjectSiteEnd = "&subareasel=";
	private final String classSiteEnd = "&idxcrs=";
	private String subjectWebsite ="";
	private String classWebsite = "";
	
	//Ready to start the service 
	private TextView debugWebsite;
	private Button startButton;
	
	////////////////Access to global function
	MyApplication mApplication ;
	//
	
	private final String TAG = "OpenClass";
	private final int CLASS_VALUE_LEN = 8;
	private final String DEFAULT_CURR_TERM = "13W";
	private Map <String,String> classDescriptionsToValues = null;
	private Map <String, String []> parsedSubjects = null;
	private Map <String,String> termDescriptionsToValues = null;
	private final int DEFAULT_DESCRIPTION_POS = 1;
	private final int DEFAULT_VALUE_POS = 0;
	private int DEFAULT_SPINNER_POS=0;
	
	//User selected values
	private String chosenTerm ;//////////
	private String spring_term ="13S";
	private String summer_term ="131";
	private String winter_term ="13W";
	
	private String chosenCategory;/////////
	private String chosenClass;/////////
	private Map <String,String> chosenClassList;/////////
	
	//Service values
	private ScanService mBoundService;
	private ServiceConnection mConnection = new ServiceConnection() {
	    public void onServiceConnected(ComponentName className, IBinder service) {
	        // This is called when the connection with the service has been
	        // established, giving us the service object we can use to
	        // interact with the service.  Because we have bound to a explicit
	        // service that we know is running in our own process, we can
	        // cast its IBinder to a concrete class and directly access it.
	        mBoundService = ( (ScanService.ServiceBinder) service ).getService();
	        Log.v(TAG,"Service is connected");
	        //Send some stuff to the service (e.g. website URL)
	    }

	    public void onServiceDisconnected(ComponentName className) {
	        // This is called when the connection with the service has been
	        // unexpectedly disconnected -- that is, its process crashed.
	        // Because it is running in our same process, we should never
	        // see this happen.
	        mBoundService = null;
	        
	    }
	};
	
	
	
	/////////////
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_interface);
        displaySubject = (TextView) findViewById(R.id.tvClassCategory);
        displayClass = (TextView) findViewById(R.id.tvClassName);

        displayTerm = (TextView) findViewById(R.id.tvClassTerm);

     
        //get, ready, set, go!!!
        startButton = (Button) findViewById (R.id.bStart);
        /////used for parsing from website
        //always map descriptions to values (clearer to the user)

        
        //listViewSelCategory.setEnabled(false); //not needed upon startup
        classDescriptionsToValues = new HashMap <String,String> ();
        parsedSubjects = new HashMap <String, String []> ();
        termDescriptionsToValues = new HashMap <String, String> ();
       chosenClassList = new HashMap <String, String> ();///////////
        
        //Allow us to access global variables and functions
        mApplication = (MyApplication) getApplicationContext();
    	//
        //This page lists class terms and class subjects
        //Bind the service starting from the beginning
        bindService(new Intent(this, ScanService.class), mConnection, Context.BIND_AUTO_CREATE);
        startButton.setOnClickListener (new View.OnClickListener () {

			@Override
			public void onClick(View v) {
				if (!classWebsite.equals(""))  //probably not necessary to check for this {
						startButton.setEnabled(false);
						mBoundService.addSite(classWebsite);
			}
			
        	
        	
        });
        //new features
        listViewSelCategory= (ListView)findViewById(R.id.listClassCategory);
        listViewSelClassName = (ListView) findViewById(R.id.listClassName);
    	radioGroupClassTerms = (RadioGroup) findViewById(R.id.rgClassTerms);
     	populateSubjects();
     	populateTerms();
   
    	
    	 
    }
    
   

    public class MyOnItemClickListener implements OnItemClickListener {

		@Override
		public void onItemClick(AdapterView<?> parent, View view, int pos,
				long id) {
			 int selectionType = parent.getId();
			  if (selectionType == R.id.listClassCategory) {
			  
		        	chosenCategory = parent.getItemAtPosition(pos).toString();
		        	Log.d(TAG,"chosen category is : "+ chosenCategory);
		        	if (!chosenCategory.equals("")) {
		        		
		        		populateClasses();

		        		
		        	}
		        	
			 }
			  else if (selectionType == R.id.listClassName) {
				  chosenClass = parent.getItemAtPosition(pos).toString();
		            if (!chosenClass.equals("")) {
		            	classWebsite ="";
		            	classWebsite = chosenClassList.get(chosenClass);
		            	//All classes end with &idxcrs=, then the ID (with spaces replaced by +s) 
		            	//see actual sample website for specifics
		            	int i = 0;
		            	String modifiedsubjectSiteEnd ="";
		            	while (i != classWebsite.length()) {
		            		if (classWebsite.charAt(i) ==' ')
		            			modifiedsubjectSiteEnd+= '+';
		            		else
		            			modifiedsubjectSiteEnd += classWebsite.charAt(i);
		                    i++;
		            		
		            	}
		            	//the "crsredir" part is changed in when using the url for getting a specific class
		            	//it should be detselect instead
		            	String target = "crsredir";
		            	String replaceTarget ="detselect";
		            	
		            	if (chosenTerm.equals(summer_term))
		            		replaceTarget+="_summer";
		            	int target_start_pos = subjectWebsite.indexOf(target);
		            	int target_end_pos = target_start_pos +target.length();
		            	Log.d(TAG,"current website: " + subjectWebsite + "\nreplaceTarget");
		                classWebsite =subjectWebsite.substring(0,target_start_pos) + replaceTarget+ subjectWebsite.substring(target_end_pos)+classSiteEnd+modifiedsubjectSiteEnd;
		                
		                //user has selected his choice...so go!
		                startButton.setEnabled(true);
		            	  Log.v(TAG, "Website is ..." +classWebsite); 
		            	}
		            
				  
			  
			  }
		
    	
    
    }
 }
 
//Create a container to parse the lists of subjects and terms
    private void populateSubjects() {
    		if (mApplication.isNetworkAvailable()) {
    			BufferedReader input = null;
    			AssetManager load_assets = this.getAssets();
    	    	String line; 
    	    	try {
    	        input = new BufferedReader(new InputStreamReader(load_assets.open("subjects.txt")));
    	            while ((line = input.readLine()) != null) { 
    	            	//form of : AERO ST {0}:Aerospace Studies {1}
    	            		String line_arr[] =line.split(":");
    	            		classDescriptionsToValues.put(line_arr[DEFAULT_DESCRIPTION_POS], line_arr[DEFAULT_VALUE_POS]);
    	            	
    	            } 

    	           input.close();
				} catch (IOException e) {
					
					e.printStackTrace();
				}
    	    	ArrayAdapter<String> adapterClassCategory = new ArrayAdapter<String>(this,
    	        		android.R.layout.simple_spinner_item);
    	       	adapterClassCategory.add(""); 
    	       	
    	       	//use a temporary variable to sort this list (for user selection convenience) of 
    	       	List <String> subjects_sorted  = new ArrayList <String> (classDescriptionsToValues.keySet());
    	       	Collections.sort(subjects_sorted);
    	    	for (String entry : subjects_sorted ) {
    	    		adapterClassCategory.add(entry);
    	    	
    	    	}
    	    	listViewSelCategory.setAdapter(adapterClassCategory);
    	    	listViewSelCategory.setOnItemClickListener(new MyOnItemClickListener());

    	    	//listViewSelCategory.setEnabled(true); //users should be able to select

    	    	//next step is to tokenize the classes for each category
    	    	//Each class subject has a special ending in the direct website link (from HTML source) based on its description
    	        //i.e. Electrical Engineering - ELEC ENGR
    	    	//i.e. African American Studies - AFRO-AM
    	    	String current [] = new String [10]  ; //tokenized string can't be more than 10 values (arbitrary)
    	    	for (Map.Entry<String,String> entry: classDescriptionsToValues.entrySet()) {
    	    			current= entry.getValue().split(" "); //tokenize based on spaces
    	    			parsedSubjects.put(entry.getKey(), current.clone()); 
    	    			 			 			
    	    	}
    	    	
    	}
    		else
    			Toast.makeText(this, "no available network to populate", Toast.LENGTH_LONG).show();
    			
    }
  
    //populate spinners with quarter terms
    private void populateTerms() {
    	

    	
    	//testing out radiogroup with terms
    	
    	
    	chosenTerm = "13W"; //by default

    	radioGroupClassTerms.check(R.id.rbTerm1); //set by default
    	radioGroupClassTerms.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
			
    	
			@Override
			public void onCheckedChanged(RadioGroup group, int checkedId) {
				radioButtonSelTerm = (RadioButton) findViewById(checkedId);
				//The chosen term values will be hardcoded for now.
    			switch (checkedId){
    			case R.id.rbTerm1:
    			chosenTerm = spring_term;
    			break;
    				
    			case R.id.rbTerm2:
    			chosenTerm = summer_term;
    			break;
    			case R.id.rbTerm3:
    			chosenTerm = winter_term;
    			break;
    			default:
    			chosenTerm = spring_term;
    			break;
    		
    			
    			
    			}
    			Toast.makeText(MainInterface.this,
        				chosenTerm, Toast.LENGTH_SHORT).show();
    			

    		        
     
    			
			}
		});
    		 
    		
    	///
    	
   
    	
    
    }
   
   
    //poplate spinner based on the selected term, subject, with actual classes
    //Electrical Engineering - ( EE115A, EE 110, EE10...)
    //return a string off containing a website with all of the classes
    //*****use only when the term and subject has been chosen *****
  private String populateClasses() {
	//first get a list of all classes under a certain subject
  	String formedURL = "";
  	formedURL += subjectSiteBegin;
  	formedURL+=chosenTerm;
  	formedURL+=subjectSiteEnd;
  	
  	String tokens [] = parsedSubjects.get(chosenCategory);
  	StringBuilder subjectEnd = new StringBuilder();
  	
  	subjectEnd.append(tokens[0]); //append this now because token must be separated by '+'
  	for (int i = 1; i < tokens.length; i++) {
  		subjectEnd.append('+' + tokens[i]);
  	}
  	formedURL+=subjectEnd;
  	subjectWebsite = formedURL;
  	String document = mApplication.readWebpage(subjectWebsite);
	/////now for a given subject, populate the classchoices
  	chosenClassList.clear();
  	
  	 
	     	
  	if (!document.equals("")) {
  	String lines [] = document.split("\n");

			String valueStartIndicator = "<option value";  //marks a line with needed values
			String valueEnd = "</option>"; //marks the end of the description wen eed
			String end = "</select"; //marks end of all possible classes
			String className, classValue;
			int startTag_pos;
			int startIndicator_pos, midIndicator_pos, endIndicator_pos;						
				//parse each Class
			   //Add each class in to selection list as we loop through it
			  ArrayAdapter<String> adapterClassList = new ArrayAdapter<String>(this,
			      		android.R.layout.simple_spinner_item);
					adapterClassList.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
			     	adapterClassList.add(""); 
			     	
				for (String line : lines) {
					startTag_pos= line.indexOf(valueStartIndicator);
					if (startTag_pos != -1) {	//we found a match
						//get beginning of the class value
						startIndicator_pos = line.indexOf('"',startTag_pos+1);
						midIndicator_pos = line.indexOf('"',startIndicator_pos+1);
						
						classValue = line.substring(startIndicator_pos+1,midIndicator_pos);
						//search for the second part (English description equivalent)
						endIndicator_pos = line.indexOf(valueEnd);
						className = line.substring(midIndicator_pos+2,endIndicator_pos); //starts exactly 2 spots after <option value ends
						chosenClassList.put(className,classValue);
						adapterClassList.add(className);
						System.out.println("Class name: " + className + "\nClass value : " + classValue);
					}
					
					else if (line.contains(end) ) {
						break;
						
					}
				}
				
     
	     //bind the lst to the view
	  	 listViewSelClassName.setAdapter(adapterClassList);
	  	 listViewSelClassName.setOnItemClickListener(new MyOnItemClickListener());
	  	 
	
	return formedURL;
  	}		
  	else 
  		return "";

}
  
  
    @Override
    protected void onDestroy() {
    	Log.d(TAG,"Getting ready to end the service");
    	 // Detach our existing connection.
        unbindService(mConnection);
        super.onDestroy();
       
    }
}
